package com.jbp.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jbp.dao.ArticleDao;
import com.jbp.model.Article;
import com.jbp.model.ArticleLike;
import com.jbp.model.User;
import com.jbp.model.UserRelation;
import com.jbp.service.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.jbp.utils.PageUtils;
import com.jbp.utils.Query;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 动态(Article)表服务实现类
 * @author cc
 * @since 2020-08-25 14:37:34
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleDao, Article> implements ArticleService {
    @Autowired
    private UserService userService;
    @Autowired
    private ArticleLikeService articleLikeService;

    @Autowired
    private UserRelationService userRelationService;

    @Autowired
    private TecentMsgService tecentMsgService;

    @Autowired
    private KeywordService keywordService;
    @Autowired
    private UserLevelService userLevelService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<Article> queryWrapper = new QueryWrapper<>();
        String authorId = (String) params.get("authorId");
        if (StringUtils.isNotEmpty(authorId)){
            queryWrapper.eq("author_id", authorId);
        }
        queryWrapper.eq("status","normal");
        String type = (String) params.get("type");
        //push推荐，new最新，focus 关注
        if ("push".equals(type)) {
            queryWrapper.orderByDesc("weight+comment_count+like_count+(SELECT level from user where id=author_id)");
        } else if ("focus".equals(type)) {
            queryWrapper.inSql("author_id", "SELECT friend_id FROM user_relation WHERE user_id="+params.get("userId")+" and (`status`=1 || `status`=2)");
            queryWrapper.orderByDesc("update_time");
        } else {
            queryWrapper.orderByDesc("update_time");
        }

        IPage<Article> page = this.page(
                new Query<Article>().getPage(params),
                queryWrapper
        );

        Integer userId = (Integer) params.get("userId");
        for (Article article : page.getRecords()) {
            fomatArticle(userId, article);
        }

        return new PageUtils(page);
    }

    /***
     * @param userId 当前用户id
     * @param article
     */
    private Article fomatArticle(Integer userId, Article article) {
        User author = userService.getById(article.getAuthorId());
        if (author!=null) {
            article.setAuthorName(author.getName());
            article.setAuthorImg(author.getImg());
            article.setAuthorSex(author.getSex());
            article.setAuthorLevel(author.getLevel());
            article.setAuthorLevelOn(userLevelService.levelOn(author.getId()));
        }

        article.setContent(keywordService.replaceKeyWord(article.getContent()));

        //是否点赞
        ArticleLike articleLike = articleLikeService.getOne(new QueryWrapper<ArticleLike>()
                .eq("article_id", article.getId())
                .eq("reader_id", userId)
        );
        article.setLiked(articleLike!=null && articleLike.getStatus().intValue()==1);

        //用户好友关系
        UserRelation userRelation = userRelationService.getByUserAndFriendId(userId, author.getId());
        if (userRelation==null) {
            article.setFriendStatus(0);
            article.setBlack(0);
        } else {
            article.setFriendStatus(userRelation.getStatus());
            article.setBlack(userRelation.getBlack());
        }
        return article;
    }

    @Override
    public void add(Article article) {
        save(article);
        User author = userService.getById(article.getAuthorId());
        if (author!=null) {
            article.setAuthorName(author.getName());
            article.setAuthorImg(author.getImg());
            article.setAuthorSex(author.getSex());
            article.setAuthorLevel(author.getLevel());
            article.setAuthorLevelOn(userLevelService.levelOn(author.getId()));
        }
        article.setLikeCount(0);
        article.setCommentCount(0);
        article.setCreateTime(new Date());
    }

    @Override
    public void remove(Integer articleId) {
        Article article = getById(articleId);
        if (article != null)  {
            article.setStatus("del");
            updateById(article);
        }
    }

    @Transactional
    @Override
    public void like(ArticleLike req) {
        Article article = getById(req.getArticleId());
        ArticleLike articleLike = articleLikeService.getOne(new QueryWrapper<ArticleLike>()
                .eq("article_id", req.getArticleId())
                .eq("reader_id", req.getReaderId())
        );
        int like = 0;
        if (articleLike!=null) {
            if (!articleLike.getStatus().equals(req.getStatus())) {
                like = req.getStatus() == 0 ? -1 : 1;
                articleLike.setStatus(req.getStatus());
                articleLikeService.updateById(articleLike);
            }
        } else {
            like = req.getStatus() == 0 ? 0 : 1;
            articleLikeService.save(req);
        }

        if (like!=0) {
            article.setLikeCount(article.getLikeCount()+like);
            updateById(article);
        }

        if (req.getStatus()==1 && !req.getReaderId().equals(article.getAuthorId())) {
            new Thread(){
                @Override
                public void run() {
                    HashMap<String, Object> map = new HashMap<>();
                    map.put("msg", "点赞了你的动态");
                    map.put("reader", userService.getById(req.getReaderId()));
                    map.put("article", getArticleById(article.getAuthorId(), req.getArticleId()));

                    tecentMsgService.sendMsgFromManger("article", article.getAuthorId().toString(), JSON.toJSONString(map));
                }
            }.start();
        }
    }

    @Override
    public Object getArticleById(Integer userId, Integer articleId) {
        return fomatArticle(userId, getById(articleId));
    }
}